package org.noote.libs.roby.scan;

import org.noote.libs.roby.configuration.RobotSettings;

import android.graphics.Bitmap;
import android.graphics.Color;

public class ScanBitmapFactory  {
	
	public int getColorSchemeCount()
	{
		return 5;
	}

	public Bitmap createFrom(RobotSettings setting, int colorScheme, ScanResult scan)
	{
		// it's scan line ?
		if(scan.getHeight() == 1)
		{
			Bitmap bitmap = Bitmap.createBitmap(scan.getWidth(), 7, Bitmap.Config.ARGB_8888);
			if(bitmap == null)
				return null;
			
			for(int l=0; l<scan.getWidth(); l++)
			{
					int val = scan.get(l,  0);
					int c = getColorFromDistance(setting, colorScheme, val);
					int bg = getColorFromDistance(setting, colorScheme, 10000);
					
					bitmap.setPixel(l, 0, bg);
					bitmap.setPixel(l, 1, bg);
					bitmap.setPixel(l, 2, c);
					bitmap.setPixel(l, 3, c);
					bitmap.setPixel(l, 4, c);
					bitmap.setPixel(l, 5, bg);
					bitmap.setPixel(l, 6, bg);
			}
		
			return bitmap;
		}
		else
		{
			Bitmap bitmap = Bitmap.createBitmap(scan.getWidth(), scan.getHeight(), Bitmap.Config.ARGB_8888);
			if(bitmap == null)
				return null;
			
			for(int l=0; l<scan.getWidth(); l++)
			{
				for(int h=0; h<scan.getHeight(); h++)
				{
					int val = scan.get(l,  h);
					int c = getColorFromDistance(setting, colorScheme, val);
					bitmap.setPixel(l, h, c);
				}
			}
		
			return bitmap;
		}
	}
	
	int getColorFromDistance(RobotSettings setting, int colorScheme, int iDistance)
	{
		if(colorScheme == 1)
			return getColorFromDistance_TwoSensors(iDistance, setting._iTurret_MinDist, setting._iTurret_MidDist, setting._iTurret_MaxDist);
		else if(colorScheme == 2)
			return getColorFromDistance_PerMeters(iDistance, setting._iTurret_MinDist);
		else  if(colorScheme == 3)
			return getColorFromDistance_Greys(iDistance, setting._iTurret_MinDist, (int)(setting._iTurret_MidDist*0.65f));
		else  if(colorScheme == 4)
			return getColorFromDistance_Greys(iDistance, setting._iTurret_MinDist, setting._iTurret_MidDist);
		
		return getColorFromDistance_BnW(iDistance, setting._iTurret_MinDist, setting._iTurret_MaxDist);
	}
	
	int getColorFromDistance_BnW(int iDistance, int iMin, int iMax)
	{
		int c = Color.YELLOW;
		if(iDistance>=iMax) c = Color.BLACK;
		else if(iDistance>=iMin)
		{
			float fC = 1.0f-((float)(iDistance-iMin)/(float)(iMax-iMin));
			int d = (int)(fC*255);
			c = Color.argb(255, d/2, d/2, d);
		}
		
		return c;
	}
	
	int getColorFromDistance_TwoSensors(int iDistance, int iMin, int iMid, int iMax)
	{
		int r0=255, r1=127, r2=0;
		int g0=255, g1=127, g2=0;
		int b0=255, b1=255, b2=0;
		
		int c = Color.YELLOW;
		if(iDistance>=iMax) c = Color.BLACK;
		else if(iDistance>=iMid)
		{
			float fC = 1.0f-((float)(iDistance-iMid)/(float)(iMax-iMid));
			int r = (int)(fC*r1 + (1.0f-fC)*r2);
			int g = (int)(fC*g1 + (1.0f-fC)*g2);
			int b = (int)(fC*b1 + (1.0f-fC)*b2);
			c = Color.argb(255, r, g, b);
		}
		else
		{
			float fC = 1.0f-((float)(iDistance-iMin)/(float)(iMid-iMin));
			int r = (int)(fC*r0 + (1.0f-fC)*r1);
			int g = (int)(fC*g0 + (1.0f-fC)*g1);
			int b = (int)(fC*b0 + (1.0f-fC)*b1);
			c = Color.argb(255, r, g, b);
		}
		
		return c;
	}
	
	int getColorFromDistance_PerMeters(int iDistance, int iMin)
	{
		int c = Color.YELLOW;
		
		if(iDistance>=iMin)
		{
			int [] r = {255,   0,   0, 255, 128,   0};
			int [] g = {  0, 255,   0, 255, 128,   0};
			int [] b = {  0,   0, 255, 255, 128,   0};

			int d=iDistance-iMin;
			int ratio = d%100;
			int zone = d/100;
			
			if(zone >= 5)
			{
				c = Color.argb(255, r[5], g[5], b[5]);
			}
			else if(ratio == 0)
			{
				c = Color.argb(255, r[zone], g[zone], b[zone]);
			}
			else
			{
				float fC = ratio/100.0f;
				
				int cr = (int)(fC*r[zone+1] + (1.0f-fC)*r[zone]);
				int cg = (int)(fC*g[zone+1] + (1.0f-fC)*g[zone]);
				int cb = (int)(fC*b[zone+1] + (1.0f-fC)*b[zone]);
				
				c = Color.argb(255, cr, cg, cb);
			}
		}
		
		return c;
	}

	int getColorFromDistance_Greys(int iDistance, int iMin, int iMax)
	{
		int c = Color.WHITE;
		
		if(iDistance>=iMax) c = Color.BLACK;
		else if(iDistance>=iMin)
		{
			float fC = 1.0f-((float)(iDistance-iMin)/(float)(iMax-iMin));
			int cg = (int) (fC*255);
			c = Color.argb(255, cg, cg, cg);
		}
		
		return c;
	}
}
